/*
 * Copyright 2017 Matthew Tamlin
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.matthewtamlin.fortytwo.library_tests;

import ohos.aafwk.content.Intent;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.ComponentState;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.components.element.StateElement;
import ohos.agp.text.Font;
import ohos.agp.utils.Color;

import com.matthewtamlin.fortytwo.library.answer.ImmutableAnswer;
import com.matthewtamlin.fortytwo.library.answer_group.SelectionLimitedAnswerGroup;
import com.matthewtamlin.fortytwo.library.answer_view.AlphaDecorator;
import com.matthewtamlin.fortytwo.library.answer_view.ColorFadeDecorator;
import com.matthewtamlin.fortytwo.library.answer_view.ColorFadeDecorator.ColorSupplier;
import com.matthewtamlin.fortytwo.library.answer_view.DecoratedAnswerCard;

import java.security.SecureRandom;

/**
 * A test harness for displaying and interacting with an {@link SelectionLimitedAnswerGroup}.
 */
public class SelectionLimitAnswerGroupTestHarness extends AnswerGroupTestHarness {
    /**
     * Supplies colors to ColorDecorators.
     */
    private final ColorSupplier colorSupplier = new ColorSupplier() {
        @Override
        public int getColor(final boolean marked, final boolean selected,
                            final boolean answerIsCorrect) {
            if (marked) {
                if (selected) {
                    return answerIsCorrect ? Color.GREEN.getValue() : Color.RED.getValue();
                } else {
                    return answerIsCorrect ? Color.RED.getValue() : Color.GREEN.getValue();
                }
            } else {
                return selected ? Color.BLUE.getValue() : Color.WHITE.getValue();
            }
        }
    };

    /**
     * Supplied alpha values to AlphaDecorators.
     */
    private final AlphaDecorator.AlphaSupplier
        alphaSupplier = new AlphaDecorator.AlphaSupplier() {
        @Override
        public float getAlpha(final boolean marked, final boolean selected,
                              final boolean answerIsCorrect) {
            if (marked && !selected && !answerIsCorrect) {
                return 0.5f;
            } else {
                return 1f;
            }
        }
    };

    /**
     * The view under test.
     */
    private SelectionLimitedAnswerGroup testView;

    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);
        getWindow().setStatusBarVisibility(Component.HIDE);
        getControlsContainer().addComponent(createIncreaseMultipleSelectionLimitButton());
        getControlsContainer().addComponent(createDecreaseMultipleSelectionLimitButton());
    }

    @Override
    public SelectionLimitedAnswerGroup getTestView() {
        if (testView == null) {
            testView = new SelectionLimitedAnswerGroup(this);
            testView.setLayoutConfig(new ComponentContainer.LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT,
                ComponentContainer.LayoutConfig.MATCH_CONTENT));
        }
        return testView;
    }

    @Override
    public DecoratedAnswerCard getAnswerView() {
        final DecoratedAnswerCard answerCard = new DecoratedAnswerCard(this);

        answerCard.addDecorator(getNewColorFadeDecorator(), false);
        answerCard.addDecorator(getNewAlphaDecorator(), false);

        if ((new SecureRandom()).nextBoolean()) {
            answerCard.setAnswer(new ImmutableAnswer("Correct", true), false);
        } else {
            answerCard.setAnswer(new ImmutableAnswer("Incorrect", false), false);
        }

        answerCard.setStatus(false, false, false);
        answerCard.setLayoutConfig(new ComponentContainer.LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT,
            ComponentContainer.LayoutConfig.MATCH_CONTENT));
        return answerCard;
    }

    /**
     * Creates a button which increases the multiple selection limit of the test view when clicked.
     *
     * @return the button
     */
    private Button createIncreaseMultipleSelectionLimitButton() {
        final Button b = new Button(this);
        configBtn(b);
        b.setText("Increase multiple selection limit");

        b.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                final int currentLimit = getTestView().getMultipleSelectionLimit();
                getTestView().setMultipleSelectionLimit(currentLimit + 1);
            }
        });

        return b;
    }

    /**
     * Creates a button which decreases the multiple selection limit of the test view when clicked.
     *
     * @return the button
     */
    private Button createDecreaseMultipleSelectionLimitButton() {
        final Button b = new Button(this);
        configBtn(b);
        b.setText("Decrease multiple selection limit");

        b.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                final int currentLimit = getTestView().getMultipleSelectionLimit() - 1;
                if (currentLimit > 0) {
                    getTestView().setMultipleSelectionLimit(currentLimit);
                }
            }
        });

        return b;
    }

    /**
     * getNewColorFadeDecorator
     *
     * @return a new ColorFadeDecorator which uses the {@code colorSupplier}
     */
    private ColorFadeDecorator getNewColorFadeDecorator() {
        return new ColorFadeDecorator(colorSupplier);
    }

    /**
     * getNewAlphaDecorator
     *
     * @return a new AlphaDecorator which uses the {@code alphaSupplier}
     */
    private AlphaDecorator getNewAlphaDecorator() {
        return new AlphaDecorator(alphaSupplier);
    }

    private void configBtn(Button b) {
        final int padding = 20;
        final int paddingTop = 25;
        final int textSize = 40;
        b.setPadding(padding, paddingTop, padding, paddingTop);
        b.setTextSize(textSize);
        b.setTextColor(new Color(Color.getIntColor("#333333")));

        StateElement stateElement = new StateElement();
        ShapeElement selectedElement = new ShapeElement(getContext(), ResourceTable.Graphic_btn_bg_press);
        ShapeElement emptyElement = new ShapeElement(getContext(), ResourceTable.Graphic_btn_bg_normal);
        stateElement.addState(new int[]{ComponentState.COMPONENT_STATE_PRESSED}, selectedElement);
        stateElement.addState(new int[]{ComponentState.COMPONENT_STATE_EMPTY}, emptyElement);
        b.setBackground(stateElement);

        b.setLayoutConfig(new ComponentContainer.LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT,
            ComponentContainer.LayoutConfig.MATCH_CONTENT));

        final int margin = 10;
        b.setMarginRight(margin);
        b.setMarginBottom(margin);
        b.setMarginLeft(margin);
        b.setMarginTop(margin);

        b.setFont(Font.DEFAULT_BOLD);
    }
}